<template>
  <view class="upload-container">
    <button class="upload-trigger" @click="selectFile">
      <text class="upload-icon">📁</text>
      <text class="upload-text">{{ buttonText || "选择文件" }}</text>
    </button>

    <view v-if="selectedFile" class="file-preview">
      <view class="file-info">
        <text class="file-name">{{ selectedFile.name }}</text>
        <text class="file-size">{{ formatFileSize(selectedFile.size) }}</text>
      </view>
      <button class="remove-btn" @click="removeFile">✕</button>
    </view>

    <button
      v-if="selectedFile"
      class="upload-btn"
      :disabled="uploading"
      @click="uploadFile"
    >
      <text v-if="!uploading">{{ uploadText || "开始上传" }}</text>
      <text v-else>上传中... {{ progress }}%</text>
    </button>

    <view v-if="uploadStatus" class="upload-status" :class="statusClass">
      <text class="status-text">{{ uploadStatus }}</text>
    </view>
  </view>
</template>

<script setup>
import { ref, computed } from "vue";

// API基础URL - 严格按照后端接口地址
const API_BASE_URL =
  import.meta.env.VITE_API_BASE_URL || "http://admin-yzy-two.wudkmao.top/api/v1";

// Props
const props = defineProps({
  buttonText: {
    type: String,
    default: "选择文件",
  },
  uploadText: {
    type: String,
    default: "开始上传",
  },
  autoUpload: {
    type: Boolean,
    default: false,
  },
});

// Emits
const emit = defineEmits(["success", "error", "progress"]);

// 响应式数据
const selectedFile = ref(null);
const uploading = ref(false);
const progress = ref(0);
const uploadStatus = ref("");

// 计算属性
const statusClass = computed(() => {
  if (uploadStatus.value.includes("成功")) return "status-success";
  if (uploadStatus.value.includes("失败")) return "status-error";
  return "status-info";
});

// H5端文件选择 - 专门为H5端优化
const selectFile = () => {
  try {
    console.log("H5端开始选择文件...");

    const input = document.createElement("input");
    input.type = "file";
    input.accept = ".pdf,.doc,.docx,.txt,.md";
    input.webkitdirectory = false;
    input.multiple = false;

    input.onchange = (e) => {
      if (e.target.files && e.target.files.length > 0) {
        const file = e.target.files[0];
        console.log("H5原始文件对象:", file);
        console.log("文件大小:", file.size, "bytes");
        console.log("文件名:", file.name);
        console.log("文件类型:", file.type);

        // 验证文件
        if (!validateFile(file)) {
          uni.showToast({
            title: "文件验证失败",
            icon: "none",
          });
          return;
        }

        // 创建文件对象
        selectedFile.value = {
          name: file.name,
          size: file.size,
          type: file.type,
          originalFile: file, // 保存原始File对象，这是关键
        };

        console.log("H5文件选择成功:", selectedFile.value);

        if (props.autoUpload) {
          uploadFile();
        }
      }
    };

    input.onerror = () => {
      uni.showToast({
        title: "文件选择失败",
        icon: "none",
      });
    };

    input.click();
  } catch (error) {
    console.error("H5端文件选择失败:", error);
    uni.showToast({
      title: "文件选择失败",
      icon: "none",
    });
  }
};

// H5端文件验证 - 专门为H5端优化
const validateFile = (file) => {
  console.log("H5端文件验证开始:", file);
  console.log("文件大小:", file.size, "bytes");
  console.log("文件名:", file.name);
  console.log("文件类型:", file.type);

  // 验证是否为文件夹
  if (file.size === 0 && !file.name.includes(".")) {
    console.error("文件验证失败：检测到文件夹");
    uni.showToast({
      title: "请选择文件，不能选择文件夹",
      icon: "none",
    });
    return false;
  }

  // 验证文件类型
  const allowedTypes = ["pdf", "doc", "docx", "txt", "md"];
  const fileExt = file.name.split(".").pop()?.toLowerCase();
  if (!allowedTypes.includes(fileExt)) {
    console.error("文件验证失败：不支持的文件类型", fileExt);
    uni.showToast({
      title: "不支持的文件类型，请选择PDF、Word、TXT或MD文件",
      icon: "none",
    });
    return false;
  }

  // 严格验证文件大小 - 防止0KB文件
  if (file.size === 0) {
    console.error("文件验证失败：文件大小为0");
    uni.showToast({
      title: "文件大小为0，请选择有效的文件",
      icon: "none",
    });
    return false;
  }

  // 验证文件大小是否合理（最小1字节，最大100MB）
  const minSize = 1; // 1字节
  const maxSize = 100 * 1024 * 1024; // 100MB

  if (file.size < minSize) {
    console.error("文件验证失败：文件太小", file.size, "bytes");
    uni.showToast({
      title: "文件太小，请选择有效的文件",
      icon: "none",
    });
    return false;
  }

  if (file.size > maxSize) {
    console.error("文件验证失败：文件太大", file.size, "bytes");
    uni.showToast({
      title: "文件太大，不能超过100MB",
      icon: "none",
    });
    return false;
  }

  console.log("H5端文件验证通过");
  return true;
};

// 移除文件
const removeFile = () => {
  selectedFile.value = null;
  progress.value = 0;
  uploadStatus.value = "";
};

// H5端文件上传 - 严格按照后端DocumentController.cs接口实现
const uploadFile = async () => {
  if (!selectedFile.value || uploading.value) return;

  try {
    uploading.value = true;
    progress.value = 0;
    uploadStatus.value = "准备上传...";

    const file = selectedFile.value;
    console.log("H5端开始上传文件:", file);

    if (!file.originalFile) {
      throw new Error("缺少原始文件对象");
    }

    // 获取认证token
    const token =
      uni.getStorageSync("token") || uni.getStorageSync("accessToken");
    if (!token) {
      throw new Error("未找到认证token，请先登录");
    }

    // 再次验证文件大小
    console.log("上传前文件大小验证:", file.originalFile.size, "bytes");
    if (file.originalFile.size === 0) {
      throw new Error("文件大小为0，无法上传");
    }

    progress.value = 10;
    uploadStatus.value = "正在上传...";

    // 严格按照后端接口创建FormData
    // 后端接口: [HttpPost("upload")] public async Task<IActionResult> UploadDocument([FromForm] IFormFile file, [FromForm] string? fileName = null)
    const formData = new FormData();

    // 关键：确保文件正确添加到FormData中
    // 对应 [FromForm] IFormFile file
    formData.append("file", file.originalFile, file.name); // 第三个参数是文件名

    // 对应 [FromForm] string? fileName = null
    if (file.name) {
      formData.append("fileName", file.name);
    }

    // 调试：检查FormData内容
    console.log("FormData内容:");
    for (let [key, value] of formData.entries()) {
      console.log(`${key}:`, value);
      if (value instanceof File) {
        console.log(`  - 文件大小: ${value.size} bytes`);
        console.log(`  - 文件名: ${value.name}`);
        console.log(`  - 文件类型: ${value.type}`);
      }
    }

    progress.value = 30;
    uploadStatus.value = "连接服务器...";

    // 严格按照后端接口地址上传
    const response = await fetch(`${API_BASE_URL}/document/upload`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${token}`,
        // 不要手动设置Content-Type，让浏览器自动设置multipart/form-data的boundary
      },
      body: formData,
    });

    progress.value = 60;
    uploadStatus.value = "处理中...";

    console.log("上传响应状态:", response.status);
    console.log("上传响应头:", response.headers);

    if (!response.ok) {
      const errorText = await response.text();
      console.error("上传失败响应:", errorText);
      throw new Error(`上传失败: ${response.status} ${errorText}`);
    }

    progress.value = 90;
    uploadStatus.value = "完成中...";

    const result = await response.json();
    console.log("H5端上传成功，返回结果:", result);

    progress.value = 100;
    uploadStatus.value = "上传完成";

    // 处理上传结果
    if (result.id || result.code === 200 || result.code === 201) {
      uploadStatus.value = "上传成功";
      emit("success", result);

      setTimeout(() => {
        selectedFile.value = null;
        uploadStatus.value = "";
        progress.value = 0;
      }, 2000);
    } else {
      throw new Error(result.message || result.error || "上传失败");
    }

    return result;
  } catch (error) {
    console.error("H5端上传失败:", error);
    uploadStatus.value = `上传失败: ${error.message}`;
    emit("error", error);
    throw error;
  } finally {
    uploading.value = false;
  }
};

// 工具函数
const formatFileSize = (bytes) => {
  if (!bytes) return "0 B";
  const k = 1024;
  const sizes = ["B", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
};

// 暴露方法给父组件
defineExpose({
  selectFile,
  uploadFile,
  removeFile,
});
</script>

<style lang="scss" scoped>
.upload-container {
  display: flex;
  flex-direction: column;
  gap: 20rpx;
}

.upload-trigger {
  background: rgba(255, 255, 255, 0.2);
  border: 2rpx dashed rgba(255, 255, 255, 0.5);
  border-radius: 20rpx;
  padding: 60rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20rpx;
  transition: all 0.3s ease;
}

.upload-trigger:active {
  transform: scale(0.98);
}

.upload-icon {
  font-size: 64rpx;
  color: rgba(255, 255, 255, 0.7);
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.upload-text {
  font-size: 32rpx;
  color: rgba(255, 255, 255, 0.8);
}

.file-preview {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 20rpx;
  padding: 30rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.file-info {
  display: flex;
  flex-direction: column;
  gap: 10rpx;
}

.file-name {
  font-size: 28rpx;
  color: white;
  font-weight: bold;
}

.file-size {
  font-size: 24rpx;
  color: rgba(255, 255, 255, 0.7);
}

.remove-btn {
  background: rgba(255, 255, 255, 0.2);
  border: none;
  border-radius: 50%;
  width: 60rpx;
  height: 60rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: 32rpx;
}

.upload-btn {
  background: #667eea;
  color: white;
  border: none;
  border-radius: 50rpx;
  padding: 30rpx;
  font-size: 32rpx;
}

.upload-btn:disabled {
  background: #ccc;
}

.upload-status {
  padding: 20rpx;
  border-radius: 10rpx;
  text-align: center;
  font-size: 28rpx;
}

.status-success {
  background: rgba(76, 175, 80, 0.2);
  color: #4caf50;
}

.status-error {
  background: rgba(244, 67, 54, 0.2);
  color: #f44336;
}

.status-info {
  background: rgba(33, 150, 243, 0.2);
  color: #2196f3;
}
</style>
